package callchain.lightcallgraph;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import soot.SootMethod;

public class SootCallGraphNodeRepo {
	private static Map<Integer, SootMethod> index2method = new HashMap<Integer, SootMethod>();
	private static int indexCounter = 0;
	
	synchronized public static void indexCallGraphNode(SootMethod cgNode){
		Collection<SootMethod> indexedMethods = index2method.values();
		if( indexedMethods.contains(cgNode) ){ // the call graph has already been indexed
			return;
		}else{
			indexCounter++;
			Integer currentIndex = new Integer(indexCounter);
			index2method.put(currentIndex, cgNode);
		}
	}
	
	public static Integer getNodeIndex(SootMethod cgNode){
		if(cgNode == null){
			return null;
		}
		
		Integer nodeIndex = null;
		Set<Integer> indexSet = index2method.keySet();
		
		for(Integer currentIndex : indexSet ){
			if(cgNode.equals(index2method.get(currentIndex))){
				nodeIndex = currentIndex;
				break;
			}
		}
		return nodeIndex;
	}
	
	public static void printRepository(){
		Set<Integer> keySet = index2method.keySet();
		StringBuilder repoStr = new StringBuilder();
		for(Integer currentKey : keySet){
			SootMethod method = index2method.get(currentKey);
			repoStr.append(currentKey);
			repoStr.append(" --> ");
			repoStr.append(method.getSignature());
			repoStr.append(" : ");
			repoStr.append(method.getDeclaringClass());
			repoStr.append("\n");
		}
		System.err.println(repoStr.toString());
	}
	
	public static void storeRepository(String fileName){
		Set<Entry<Integer, SootMethod>> entrySet = index2method.entrySet();
		StringBuilder repoStr = new StringBuilder();
		for(Entry<Integer, SootMethod> currentEntry : entrySet){
			Integer currentKey = currentEntry.getKey();
			SootMethod currentMethod = currentEntry.getValue();
			repoStr.append(currentKey);
			repoStr.append(" ");
			repoStr.append(currentMethod.getSignature());
			repoStr.append("\n");
		}
		
		try {
			PrintWriter pw = new PrintWriter(fileName);
			pw.print(repoStr.toString());
			pw.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}
